package work.thread_eg.pool;

import cn.hutool.core.date.DateUtil;

import java.util.concurrent.*;

/**
 *
 * 定长线程池
 *
 * 注意点
 *      1 创建一个固定大小的线程池, 可控制并发的线程数, 超出的线程会在队列中等待
 *        (过多的线程放到阻塞队列 LinkedBlockingQueue中等待)
 *        LinkedBlockingQueue队列容量大小是Integer.MAX_VALUE (容量很大的有界队列), 一般不会触发拒绝策略
 *        如果同时创建很多线程, 任务队列堆积, 占用大量内存导致 OOM
 *      2 因为线程池大小是固定的, 这里设置的是3个线程, 所以线程名只有3个
 *        因为线程不足会进入队列等待线程空闲,  所以日志间隔2秒输出
 *        workQueue里面最多存放了 7个任务
 *
 */
public class FixedThreadPoolMain {
    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            executorService.execute(() -> {
                // 获取线程名称,默认格式:pool-1-thread-1
                System.out.println(DateUtil.now() + " " + Thread.currentThread().getName() + " " + index);
                // 等待2秒
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException exception) {
                    exception.printStackTrace();
                }
            });
            System.out.println("线程池中线程数目：" + executorService.getPoolSize() + "，队列中等待执行的任务数目：" +
                    executorService.getQueue().size() + "，已执行玩别的任务数目：" + executorService.getCompletedTaskCount());
        }
    }
}
